using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using OpenComposite.Base.Designer;
using OpenComposite.Repository.Properties;
using OpenComposite.EII.Repository;
using System.Text;

namespace OpenComposite.EII.Designer.BUSView
{
	public class BUSDocumentSymbol : Symbol
	{
		#region Initialization
		static BUSDocumentSymbol()
		{
			if ( _img == null ) {
				_img = (Bitmap)Resources.Document.Clone();
				_img.MakeTransparent(Color.Magenta);
			}
			if ( _sf == null ) {
				_sf = new StringFormat(StringFormat.GenericDefault);
				_sf.Alignment = StringAlignment.Near;
				_sf.LineAlignment = StringAlignment.Center;
				_sf.Trimming = StringTrimming.EllipsisCharacter;
				_sf.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
			}
		}

		public BUSDocumentSymbol()
		{
			init();
		}
		private void init()
		{
			this.BeginUpdate();

			_selectedIndex = -1;
			_bobjColl = new NamedBusinessObjectCollection(this);
			_isPublish = true;

			this.MinimumSize = new Size(16, 16);
			this.Size = new Size(16, 16);
			this.TopLevel = true;

			this.Text = "";

			this.Border = BorderType.None;

			this.BackColor = Color.FromArgb(128, Color.White);
			this.ForeColor = Color.Black;

			this.NameTextBox.Remove();
			//this.NameTextBox.BackColor = Color.Transparent;

			this.ContextMenuStrip.Items.Clear();
			this.ContextMenuStrip.Items.Add(
				"View Schema...",
				null,
				new EventHandler(this.ViewSchema_Click));
			this.ContextMenuStrip.Items.Add(new ToolStripSeparator());
			this.ContextMenuStrip.Items.Add(
				"Remove Document",
				Resources.ico_delete_16x.ToBitmap(),
				new EventHandler(this.RemoveDocument_Click));
			this.ContextMenuStrip.Items.Add(new ToolStripSeparator());
			this.ContextMenuStrip.Items.Add(
				"Remove All Documents",
				Resources.ico_delete_16x.ToBitmap(),
				new EventHandler(this.RemoveAllDocuments_Click));

			if ( _sf == null ) {
				_sf = new StringFormat(StringFormat.GenericDefault);
				_sf.Alignment = StringAlignment.Near;
				_sf.LineAlignment = StringAlignment.Center;
				_sf.Trimming = StringTrimming.EllipsisCharacter;
				_sf.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
			}

			base.Tooltip = new ToolTip();
			base.Tooltip.AutoPopDelay = 20000;
			base.Tooltip.UseFading = false;
			base.Tooltip.UseAnimation = false;
			base.Tooltip.ShowAlways = false;
			this.EndUpdate();
		}
		#endregion

		#region Public Members

		#region Properties
		// new
		public bool IsPublishedDocument
		{
			get { return _isPublish; }
			set
			{
				if ( _isPublish != value ) {
					_isPublish = value;
					// set StringFormat
					if ( _isPublish ) {
						_sf.Alignment = StringAlignment.Near;
					} else {
						_sf.Alignment = StringAlignment.Far;
					}
					Refresh();
				}
			}
		}
		public NamedBusinessObjectCollection NamedBusinessObjects
		{
			get { return _bobjColl; }
		}
		public BusinessObject SelectedBusinessObject
		{
			get
			{
				if ( _selectedIndex >= 0 && _selectedIndex < _bobjColl.Count )
					return _bobjColl[_selectedIndex].BusinessObject;
				else
					return null;
			}
		}
		public NamedBusinessObject SelectedNamedBusinessObject
		{
			get
			{
				if ( _selectedIndex >= 0 && _selectedIndex < _bobjColl.Count )
					return _bobjColl[_selectedIndex];
				else
					return null;
			}
		}
		public int SelectedIndex
		{
			get { return _selectedIndex; }
			set
			{
				if ( _selectedIndex != value ) {
					_selectedIndex = value;
					OnSelectedIndexChanged();
				}
			}
		}

		// override
		public override bool CanFocused
		{
			get
			{
				return true;
			}
		}
		public override bool CanMove
		{
			get
			{
				return false;
			}
		}
		public override bool CanResize
		{
			get
			{
				return false;
			}
		}
		public override bool CanSelect
		{
			get
			{
				return true;
			}
		}
		public override bool NoClip
		{
			get
			{
				return true;
			}
		}
		public override bool UseGrid
		{
			get
			{
				return false;
			}
		}
		public override string Text
		{
			get
			{
				return base.Text;
			}
			set
			{
				base.Text = value;
			}
		}
		#endregion

		#region Events
		public event EventHandler BusinessObjectsListChanged = null;
		#endregion

		#region Methods
		public override void Paint(System.Windows.Forms.PaintEventArgs pe)
		{
			int y = 0;
			Rectangle r = this.GetPaintBounds();
			foreach ( NamedBusinessObject item in this.NamedBusinessObjects ) {
				if ( item == null ) continue;
				bool selected = ( item == this.SelectedNamedBusinessObject );
				Point pImg;
				Rectangle rTxt;

				pImg = this.IsPublishedDocument ?
						new Point(r.X, r.Y + y) :
						new Point(r.X + this.Width - _img.Width, r.Y + y);

				rTxt = this.IsPublishedDocument ?
						new Rectangle(r.X + this.TextStartPosition, r.Y + y,
									   Math.Min(r.Width - this.TextStartPosition,130), cItemHeight) :
						new Rectangle(r.X, r.Y + y,
									   Math.Min(r.Width - this.TextStartPosition, 130), cItemHeight);
				if ( selected )
					pe.Graphics.FillRectangle(SystemBrushes.Highlight, new Rectangle(r.X, r.Y + this.SelectedIndex * cItemHeight, r.Width, cItemHeight));
				pe.Graphics.DrawImageUnscaled(BUSDocumentSymbol.DocumentImage, pImg);
				string display = getDisplayedText(item);
				pe.Graphics.DrawString(display, this.Font,
									   ( selected ? SystemBrushes.HighlightText : this.ForeBrush ),
									   rTxt, BUSDocumentSymbol.TextFormat);
				//tooltip += string.Format("{0}{1}", display, Environment.NewLine);
				y += cItemHeight;
			}
		}

		public override string ToolText
		{
			get
			{
				StringBuilder sb = new StringBuilder();
				foreach ( NamedBusinessObject item in this.NamedBusinessObjects ) {
					sb.AppendLine(getDisplayedText(item));
				}
				return sb.ToString();
			}
			protected set
			{
				base.ToolText = value;
			}
		}

		public override object GetDragObject(Point location, System.Windows.Forms.MouseButtons button)
		{
			return this.SelectedNamedBusinessObject;
		}
		public override void ReadXml(System.Xml.XmlReader reader)
		{
			return;
		}
		public override void WriteXml(System.Xml.XmlWriter writer)
		{
			return;
		}
		#endregion


		#endregion

		#region Protected Members

		#region Properties
		// static
		protected static Bitmap DocumentImage
		{
			get { return _img; }
		}
		protected static StringFormat TextFormat
		{
			get { return _sf; }
		}

		// new
		protected int TextStartPosition
		{
			get { return _img.Width + 2; }
		}
		#endregion

		#region Methods
		// virtual
		protected virtual void UpdateSymbol()
		{
			int h, w;
			this.BeginUpdate();

			h = MeasureHeight();
			w = MeasureWidth();

			this.Size = new Size(w, h);
			this.Refresh();
			this.EndUpdate();
		}
		protected virtual int MeasureHeight()
		{
			return cItemHeight * this.NamedBusinessObjects.Count;
		}
		protected virtual int MeasureWidth()
		{
			int max = _img.Width;
			if ( this.DesignerViewControl != null ) {
				using ( Graphics g = this.DesignerViewControl.CreateGraphics() ) {
					SizeF szF = g.MeasureString(this.Text, this.Font);
					max = (int)Math.Ceiling(szF.Width);
					foreach ( NamedBusinessObject item in this.NamedBusinessObjects ) {
						if ( item == null || item.BusinessObject == null ) continue;
						szF = g.MeasureString(getDisplayedText(item), this.Font);
						int currentWidth = _img.Width + 2 + (int)Math.Ceiling(szF.Width);
						if ( max < currentWidth )
							max = Math.Min(currentWidth, 150);
					}
				}
			}
			return max;
		}
		protected virtual int GetSelectedIndex(System.Windows.Forms.MouseEventArgs e)
		{
			if ( this.Parent == null ) {
				return ( e.Y - this.Top ) / cItemHeight;
			} else {
				Point pt = this.Parent.PointToDesignerControlClient(e.Location);
				return ( pt.Y - this.Top ) / cItemHeight;
			}
		}

		internal virtual void OnBusinessObjectAdded()
		{
			UpdateSymbol();
			OnBusinessObjectsListChanged();
		}
		internal virtual void OnBusinessObjectRemoved()
		{
			UpdateSymbol();
			OnBusinessObjectsListChanged();
		}
		internal virtual void OnBusinessObjectsCleared()
		{
			UpdateSymbol();
			OnBusinessObjectsListChanged();
		}
		internal virtual void OnBusinessObjectsListChanged()
		{
			EventHandler tmp = this.BusinessObjectsListChanged;
			if ( tmp != null ) {
				tmp(this, EventArgs.Empty);
			}
		}

		protected virtual void OnSelectedIndexChanged()
		{
			this.Refresh();
		}

		// override
		protected override void OnTextChanged(EventArgs e)
		{
			base.OnTextChanged(e);
		}
		internal void OnLayout()
		{
			UpdateSymbol();
		}
		protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
		{
			this.SelectedIndex = GetSelectedIndex(e);
			base.OnMouseMove(e);
		}
		protected override void OnMouseLeave(EventArgs e)
		{
			this.SelectedIndex = -1;
			base.OnMouseLeave(e);
		}

		// new
		#endregion

		#region Constants
		protected const int cItemHeight = 18;
		#endregion

		#endregion

		#region Private Members

		#region Variables
		private bool _isPublish;
		private NamedBusinessObjectCollection _bobjColl;
		private int _selectedIndex;
		#endregion

		#region Static
		private static Bitmap _img = null;
		private static StringFormat _sf = null;
		#endregion

		#region Methods
		private bool SimpleMode
		{
			get
			{
				BUSViewController bvc = this.DesignerViewControl.DesignController as BUSViewController;
				if ( bvc == null ) return false;
				else return bvc.SimpleMode;
			}
		}
		private string getDisplayedText(NamedBusinessObject item)
		{
			if ( item.BusinessObject.WorkflowField != null ) {		
				return item.BusinessObject.WorkflowField.BusinessObject != null && SimpleMode ? item.BusinessObject.WorkflowField.BusinessObject.Name : item.Name;
			}
			return SimpleMode ? item.BusinessObject.Name : item.Name;
		}
		#endregion

		#region Event Handlers
		private void RemoveDocument_Click(object sender, EventArgs e)
		{
			this.BeginUpdate();
			BusinessObject boSelected = this.SelectedBusinessObject;
			if ( boSelected != null ) {
				this.SelectedIndex = -1;
				this.NamedBusinessObjects.Remove(boSelected);
			}
			UpdateSymbol();
			this.EndUpdate();
		}
		private void RemoveAllDocuments_Click(object sender, EventArgs e)
		{
			this.Remove();
		}
		private void ViewSchema_Click(object sender, EventArgs e)
		{
			if ( this.SelectedBusinessObject != null ) {
				formXmlViewer frm = new formXmlViewer();
				XmlDocument xd = new XmlDocument();
				xd.LoadXml(this.SelectedBusinessObject.SchemaString);
				frm.XmlDocument = xd;
				frm.ShowDialog();
			}
		}
		#endregion

		#endregion

	}


}
